package sy4_Creational_Pattern.builder.zhangBuilder;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
class Product{   //复杂产品角色
    //产品部件的名称
    private String food;
    private String drink;
}

abstract class Builder{   //抽象建造者
    Product product = new Product();  //关联

    //定义复杂产品部件建造的抽象方法
    public abstract void buildFood();  //建造食品
    public abstract void buildDrink();  //建造饮料

    public Product getProduct(){   //普通方法，供产品指挥者调用
        return product;  //产品建造过程由产品指挥者控制
    }
}

class ConcreteBuilderA extends Builder{  //麦当劳快餐
    public ConcreteBuilderA() {
        System.out.println("麦当劳快餐");
    }
    @Override
    public void buildFood() {
        product.setFood("汉堡");  //setter建造结果
    }
    @Override
    public void buildDrink() {
        product.setDrink("可口可乐");  //setter建造结果
    }
}

class ConcreteBuilderB extends Builder{  //肯德鸡快餐
    public ConcreteBuilderB() {
        System.out.println("肯德鸡快餐");
    }
    @Override
    public void buildFood() {
        product.setFood("炸鸡");   //setter建造结果
    }
    @Override
    public void buildDrink() {
        product.setDrink("百事可乐");   //setter建造结果
    }
}

class Director{   //指挥者
    //Director同时依赖 Builder和 Product，可修改为Director与Builder为组合关系且Director与Product为依赖关系
    public Product buildProduct(Builder builder){
        //建造过程控制，可注释部分语句
        builder.buildFood();
        builder.buildDrink();
        return builder.getProduct();  //返回产品
    }
}

public class Client {
    public static void main(String[] args) {
        //通过产品指挥者，隔离了产品的建造细节
        Director director = new Director();  //创建产品指挥者
        //调用构建产品方法，以具体构建者作为方法参数
        Product product = director.buildProduct(new ConcreteBuilderA());
        System.out.println(product);
        //相同的建造过程，可以有不同的产品表示
        product = director.buildProduct(new ConcreteBuilderB());  //方法调用
        System.out.println(product);
    }
}
